/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */
#pragma once

#include <animate/Node.h>
#include <lib3d/Math_lib3d.h>
#include <lib3d/CameraDesc.h>
#include <Atom.h>
#include <WowPtr.h>
#include <SharedRep.h>
#include <list>
#include <xml/Object.h>
#include <NoCopy.h>
#include <font/GenericFont.h>
#include <filesystem/String.hpp>
#include "Node.h"
#include <map>
#include <memory>
#include "TextData.h"
#include "TextImpl.h"
#include <CompilerFeatures.h>

namespace liba {
namespace lib3d {
namespace node {

class Text 
	: public Node
	, public xml::ObjectUnicode
	, public Shared<filesystem::String, font::GenericFont>
{
	NODE_DEFINITION(Text)
public:
	enum Alignment { LEFT, CENTER, RIGHT };

	static converter::EnumPair<char, TextData::Alignment> AlignmentNames[];

	static const Atom node_name;

	Text( const Atom & name, Node * parent );
	Text( const Text & other );
	virtual ~Text();
	virtual Text * Clone() LIBA_OVERRIDE;

	// Attributes
	static const Atom text_name;
	static const Atom font_name;
	static const Atom alignment_name;
	static const Atom valignment_name;
	static const Atom COLOR_NAME;
	static const Atom TRANSPARENCY_NAME;
	static const Atom check_letters_name;
	// Nodes
	static const Atom shader_name;

	virtual void RenderToList( hard::Hardware * hardware, hard::RenderList * render_list ) LIBA_OVERRIDE;

	void change_text(const std::wstring & text, bool parseEscapes = false);
	void change_text(const std::string & text, bool parseEscapes = false);

	void change_font(const filesystem::String & path);
	void change_alignment(Alignment alignmentValue);
	void change_max_width(int value);
	
	const std::wstring & get_text()const;
	filesystem::String get_font()const;
	Alignment get_alignment()const;

	float get_text_width(const std::wstring & text);
	float get_text_height();

	virtual void CreateProxy(ProxyVisitor * proxyVisitor) LIBA_OVERRIDE;

	std::string GetTextID() const
	{
		return textID;
	}

	void SetTextID(const std::string & value)
	{
		textID = value;
	}
protected:
	virtual bool on_attribute( xml::Provider * prov, const std::wstring & name, const std::wstring & value ) LIBA_OVERRIDE;
	virtual bool on_attribute( xml::Provider * prov, const std::string & name, const std::string & value ) LIBA_OVERRIDE;
	virtual bool on_end_node( xml::Provider * prov ) LIBA_OVERRIDE;
	virtual void on_save_attributes( xml::SaverBase * saver )const LIBA_OVERRIDE;
	virtual void on_save_nodes( xml::SaverBase * saver )const LIBA_OVERRIDE;
private:
	void textDataChanged();

	TextData textData;

	properties::DependencyProperty<Color> color;
	properties::DependencyProperty<float> transparency;

	std::auto_ptr<TextImpl> impl;

	filesystem::String fontFile;
	std::string textID;

	void TextChanged(const std::wstring& value);
	properties::DependencyProperty<std::wstring> text;

	void FontChanged(const std::wstring& value);
	properties::DependencyProperty<std::wstring> font;
};

} // namespace node
} // namespace lib3d

namespace converter{

template<>
struct ConverterTraits<char, lib3d::node::TextData::Alignment>
:	public ConverterTraitsEnumBase<char, lib3d::node::TextData::Alignment, lib3d::node::Text::AlignmentNames>
{};

} // namespace converter


} // namespace liba
using namespace liba;
